<%#
 Copyright 2013-2025 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      https://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
import { vitest } from 'vitest';
import { computed } from 'vue';
import { shallowMount } from '@vue/test-utils';
import { type Router } from 'vue-router';
import { createTestingPinia } from '@pinia/testing';

import { useStore } from '@/store';
import { createRouter } from '@/router';
<%_ if (authenticationUsesCsrf) { _%>
import type LoginService from '@/account/login.service';
<%_ } _%>
<%_ if (generateUserManagement) { _%>
import { useLoginModal } from '@/account/login-modal';
<%_ } _%>
import JhiNavbar from './jhi-navbar.vue';
<%_ if (applicationTypeGateway && microfrontend) { _%>

vitest.mock('@module-federation/enhanced/runtime', () => ({
  loadRemote: vitest.fn(() => Promise.reject(new Error('Test only'))),
}));
<%_ } _%>

type JhiNavbarComponentType = InstanceType<typeof JhiNavbar>;

const pinia = createTestingPinia({ stubActions: false });
const store = useStore();

describe('JhiNavbar', () => {
  let jhiNavbar: JhiNavbarComponentType;
<%_ if (authenticationUsesCsrf) { _%>
  let loginService: LoginService;
<%_ } _%>
<%_ if (generateUserManagement) { _%>
  let login: ReturnType<typeof useLoginModal>;
<%_ } _%>
  const accountService = { hasAnyAuthorityAndCheckAuth: vitest.fn().mockImplementation(() => Promise.resolve(true)) };
<%_ if (enableTranslation) { _%>
  const changeLanguage = vitest.fn();
<%_ } _%>
  let router: Router;

  beforeEach(() => {
    router = createRouter();
<%_ if (authenticationUsesCsrf) { _%>
    loginService = { login: vitest.fn(), logout: vitest.fn() };
<%_ } _%>
    const wrapper = shallowMount(JhiNavbar, {
      global: {
        plugins: [pinia, router],
        stubs: {
          'font-awesome-icon': true,
          'b-navbar': true,
          'b-navbar-nav': true,
          'b-dropdown-item': true,
          'b-collapse': true,
          'b-nav-item': true,
          'b-nav-item-dropdown': true,
          'b-navbar-toggle': true,
          'b-navbar-brand': true,
        },
        provide: {
<%_ if (authenticationUsesCsrf) { _%>
          loginService,
<%_ } _%>
          currentLanguage: computed(() => 'foo'),
<%_ if (enableTranslation) { _%>
          changeLanguage,
<%_ } _%>
          accountService,
        },
      },
    });
    jhiNavbar = wrapper.vm;
<%_ if (generateUserManagement) { _%>
    login = useLoginModal();
<%_ } _%>
  });

  it('should not have user data set', () => {
    expect(jhiNavbar.authenticated).toBeFalsy();
    expect(jhiNavbar.openAPIEnabled).toBeFalsy();
    expect(jhiNavbar.inProduction).toBeFalsy();
  });

  it('should have user data set after authentication', () => {
    store.setAuthentication({ login: 'test' });

    expect(jhiNavbar.authenticated).toBeTruthy();
  });

  it('should have profile info set after info retrieved', () => {
    store.setActiveProfiles(['prod', 'api-docs']);

    expect(jhiNavbar.openAPIEnabled).toBeTruthy();
    expect(jhiNavbar.inProduction).toBeTruthy();
  });

  it('should use login service', () => {
    jhiNavbar.<% if (authenticationTypeOauth2) { %>login<% } else { %>showLogin<% } %>();

<%_ if (authenticationTypeOauth2) { _%>
    expect(loginService.login).toHaveBeenCalled();
<%_ } else { _%>
    expect(login.showLogin).toHaveBeenCalled();
<%_ } _%>
  });

  it('should use account service', () => {
    jhiNavbar.hasAnyAuthority('auth');

    expect(accountService.hasAnyAuthorityAndCheckAuth).toHaveBeenCalled();
  });

  it('logout should clear credentials', async () => {
    store.setAuthentication({ login: 'test' });
<%_ if (authenticationTypeOauth2) { _%>
    const logoutUrl = '/to-match';
    (loginService.logout as any).mockReturnValue(Promise.resolve({ data: { logoutUrl } }));
<%_ } else if (authenticationUsesCsrf) { _%>
    (loginService.logout as any).mockReturnValue(Promise.resolve({}));
<%_ } _%>

    await jhiNavbar.logout();

<%_ if (!authenticationTypeJwt) { _%>
    expect(loginService.logout).toHaveBeenCalled();
  <%_ if (authenticationTypeOauth2) { _%>
    expect(router.currentRoute.value.path).toBe(logoutUrl);
  <%_ } _%>
<%_ } else { _%>
    expect(jhiNavbar.authenticated).toBeFalsy();
<%_ } _%>
  });

  it('should determine active route', async () => {
    await router.push('/forbidden');

    expect(jhiNavbar.subIsActive('/titi')).toBeFalsy();
    expect(jhiNavbar.subIsActive('/forbidden')).toBeTruthy();
    expect(jhiNavbar.subIsActive(['/forbidden', 'forbidden'])).toBeTruthy();
  });

<%_ if (enableTranslation) { _%>
  it('should call translationService when changing language', () => {
    jhiNavbar.changeLanguage('fr');

    expect(changeLanguage).toHaveBeenCalled();
  });

  it('should check for correct language', () => {
    expect(jhiNavbar.isActiveLanguage('en')).toBeFalsy();
    expect(jhiNavbar.isActiveLanguage('foo')).toBeTruthy();
  });
<%_ } _%>
});
